﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Assignment
{
    public partial class Form1 : Form
    {
        private string directoryRoot;
      
        // Blocking queue
        private ConcurrentQueue<IList<string>> blockingQueue = new ConcurrentQueue<IList<string>>();

        // Producer for blocking queue
        private FileReader reader;

        // Consumer 
        private FileWriter writer;

        private string restartReaders = "Restart Readers";

        private string startReaders = "Start Readers";

        private string restartWriter = "Restart Writer";

        private string startWriter = "Start Writer";

        private string pauseWriterText = "Pause Writer";

        private string resumeWriterText = "Resume Writer";

        private string pauseReadersText = "Pause Readers";

        private string resumeReadersText = "Resume Readers";

        private int threads = 1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox1.Text = threads.ToString();

            button3.Enabled = false;
            button4.Enabled = false;
            button6.Enabled = false;
            button5.Enabled = false;
        }

        private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                threads = Int32.Parse(textBox1.Text);

                if (threads <= 0)
                {
                    MessageBox.Show(
                        "Number of threads must be a positive integer !",
                        "Invalid number of threads",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Exclamation);
                }
                else
                {
                    if (string.IsNullOrEmpty(directoryRoot))
                    {
                        MessageBox.Show(
                            "The directory to search for files has to be set !",
                            "Search directory not set",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        button1.Enabled = false;
                        button3.Enabled = true;
                        button6.Enabled = true;

                        if (button1.Text.Equals(startReaders))
                        {
                            button1.Text = restartReaders;
                            reader = new FileReader(blockingQueue, directoryRoot, threads);
                            reader.Read();
                        }
                        else
                        {
                            // Restart readers
                            reader.Restart();
                        }
                    }
                }
            }
            catch (FormatException)
            {
                MessageBox.Show(
                    "Unable to parse the number of threads field. It must be a positive integer !",
                    "Invalid number of threads",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    ex.Message,
                    "Error starting readers",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
            }
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox3.Text))
            {
                MessageBox.Show(
                    "Full path for the output file name cannot be empty !",
                    "Missing parameer",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
            }
            else
            {
                button4.Enabled = true;
                button5.Enabled = true;
                button2.Enabled = false;

                if (button2.Text.Equals(startWriter))
                {
                    button2.Text = restartWriter;
                    writer = new FileWriter(blockingQueue, textBox3.Text);
                    writer.Write();
                }
                else
                {
                    // Restart writer
                    writer.Restart();
                }
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (button3.Text.Equals(pauseReadersText))
            {
                reader.Pause();
                button3.Text = resumeReadersText;
            }
            else if (button3.Text.Equals(resumeReadersText))
            {
                reader.Resume();
                button3.Text = pauseReadersText;
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                directoryRoot = folderBrowserDialog1.SelectedPath;
                textBox2.Text = directoryRoot;
            }
        }

        // Abort button click
        private void button6_Click(object sender, EventArgs e)
        {
            reader.Abort();

            button3.Enabled = false;
            button6.Enabled = false;
            button1.Enabled = true;
            button3.Text = pauseReadersText;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (button4.Text.Equals(pauseWriterText))
            {
                writer.Pause();
                button4.Text = resumeWriterText;
            }
            else if (button4.Text.Equals(resumeWriterText))
            {
                button4.Text = pauseWriterText;
                writer.Resume();
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            writer.Abort();

            button4.Enabled = false;
            button5.Enabled = false;
            button2.Enabled = true;
            button4.Text = pauseWriterText;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog2.ShowDialog() == DialogResult.OK)
            {
                textBox3.Text = Path.Combine(folderBrowserDialog2.SelectedPath, "output.txt");
            }
        }
    }
}
